//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift project authors.
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

#pragma once

// C Stdlib
#include <errno.h>

// Pico SDK
#include <pico/cyw43_arch.h>
#include <pico/multicore.h>
#include <pico/stdlib.h>

#include <hardware/clocks.h>
#include <hardware/dma.h>
#include <hardware/i2c.h>
#include <hardware/pio.h>
#include <hardware/sync.h>

// Bluetooth SDK
#include <btstack.h>
#include <btstack_event.h>
#include <btstack_resample.h>
#include <btstack_run_loop.h>

// PIO Programs
#include "I2S.pio.h"
#include "QuadratureEncoder.pio.h"
#include "WS2812.pio.h"

#undef ISB
#include "arm_math.h"

// Shims
static inline pio_hw_t* _pio0(void) { return pio0; }
static inline pio_hw_t* _pio1(void) { return pio1; }
static inline int32_t _errno() { return errno; }

static const q15_t _samples_512[512] = {
  // 10000 Hz
  // 0, 32419, 9435, -29673, -18071, 24413, 25176, -17086, -30149, 8311, 32568, 1166, -32228, -10546, 29159, 19033, -23619, -25907, 16079, 30587, -7177, -32676, -2332, 31997, 11644, -28608, -19971, 22796, 26605, -15052, -30986, 6034, 32742, 3494, -31725, -12728, 28021, 20883, -21943, -27269, 14006, 31346, -4883, -32767, -4652, 31413, 13795, -27398, -21769, 21062, 27899, -12943, -31666, 3726, 32751, 5805, -31061, -14845, 26741, 22627, -20155, -28493, 11862, 31946, -2565, -32692, -6949, 30670, 15876, -26049, -23457, 19222, 29052, -10767, -32185, 1400, 32593, 8085, -30240, -16886, 25325, 24257, -18265, -29573, 9658, 32384, -233, -32452, -9211, 29771, 17876, -24568, -25026, 17285, 30057, -8537, -32541, -933, 32270, 10325, -29265, -18842, 23781, 25763, -16282, -30502, 7405, 32658, 2099, -32047, -11426, 28721, 19785, -22963, -26468, 15259, 30909, -6263, -32732, -3262, 31783, 12512, -28141, -20703, 22116, 27139, -14217, -31277, 5114, 32766, 4421, -31479, -13583, 27525, 21594, -21241, -27776, 13157, 31605, -3958, -32757, -5575, 31135, 14636, -26875, -22458, 20339, 28377, -12080, -31893, 2797, 32707, 6721, -30751, -15671, 26190, 23293, -19411, -28943, 10987, 32141, -1633, -32616, -7859, 30329, 16686, -25472, -24099, 18458, 29472, -9881, -32347, 466, 32483, 8987, -29868, -17679, 24722, 24875, -17483, -29963, 8762, 32513, 700, -32309, -10103, 29369, 18651, -23941, -25619, 16484, 30416, -7632, -32638, -1866, 32094, 11207, -28833, -19598, 23129, 26330, -15466, -30831, 6492, 32721, 3030, -31839, -12296, 28260, 20521, -22287, -27008, 14427, 31207, -5344, -32762, -4190, 31543, 13370, -27651, -21418, 21418, 27651, -13370, -31543, 4190, 32762, 5344, -31207, -14427, 27008, 22287, -20521, -28260, 12296, 31839, -3030, -32721, -6492, 30831, 15466, -26330, -23129, 19598, 28833, -11207, -32094, 1866, 32638, 7632, -30416, -16484, 25619, 23941, -18651, -29369, 10103, 32309, -700, -32513, -8762, 29963, 17483, -24875, -24722, 17679, 29868, -8987, -32483, -466, 32347, 9881, -29472, -18458, 24099, 25472, -16686, -30329, 7859, 32616, 1633, -32141, -10987, 28943, 19411, -23293, -26190, 15671, 30751, -6721, -32707, -2797, 31893, 12080, -28377, -20339, 22458, 26875, -14636, -31135, 5575, 32757, 3958, -31605, -13157, 27776, 21241, -21594, -27525, 13583, 31479, -4421, -32766, -5114, 31277, 14217, -27139, -22116, 20703, 28141, -12512, -31783, 3262, 32732, 6263, -30909, -15259, 26468, 22963, -19785, -28721, 11426, 32047, -2099, -32658, -7405, 30502, 16282, -25763, -23781, 18842, 29265, -10325, -32270, 933, 32541, 8537, -30057, -17285, 25026, 24568, -17876, -29771, 9211, 32452, 233, -32384, -9658, 29573, 18265, -24257, -25325, 16886, 30240, -8085, -32593, -1400, 32185, 10767, -29052, -19222, 23457, 26049, -15876, -30670, 6949, 32692, 2565, -31946, -11862, 28493, 20155, -22627, -26741, 14845, 31061, -5805, -32751, -3726, 31666, 12943, -27899, -21062, 21769, 27398, -13795, -31413, 4652, 32767, 4883, -31346, -14006, 27269, 21943, -20883, -28021, 12728, 31725, -3494, -32742, -6034, 30986, 15052, -26605, -22796, 19971, 28608, -11644, -31997, 2332, 32676, 7177, -30587, -16079, 25907, 23619, -19033, -29159, 10546, 32228, -1166, -32568, -8311, 30149, 17086, -25176, -24413, 18071, 29673, -9435, -32419, 0, 32419, 9435, -29673, -18071, 24413, 25176, -17086, -30149, 8311, 32568, 1166, -32228, -10546, 29159, 19033, -23619, -25907, 16079, 30587, -7177, -32676, -2332, 31997, 11644, -28608, -19971, 22796, 26605, -15052, -30986, 6034, 32742, 3494, -31725, -12728, 28021, 20883, -21943, -27269, 14006, 31346, -4883, -32767, -4652, 31413, 13795, -27398, -21769, 21062, 27899, -12943, -31666, 3726, 32751, 5805, -31061, -14845, 26741, 22627, -20155, -28493, 11862, 31946, -2565, -32692, -6949, 30670, 15876, -26049, -23457
  // 100 Hz
  // 0, 466, 933, 1400, 1866, 2332, 2797, 3262, 3726, 4190, 4652, 5114, 5575, 6034, 6492, 6949, 7405, 7859, 8311, 8762, 9211, 9658, 10103, 10546, 10987, 11426, 11862, 12296, 12728, 13157, 13583, 14006, 14427, 14845, 15259, 15671, 16079, 16484, 16886, 17285, 17679, 18071, 18458, 18842, 19222, 19598, 19971, 20339, 20703, 21062, 21418, 21769, 22116, 22458, 22796, 23129, 23457, 23781, 24099, 24413, 24722, 25026, 25325, 25619, 25907, 26190, 26468, 26741, 27008, 27269, 27525, 27776, 28021, 28260, 28493, 28721, 28943, 29159, 29369, 29573, 29771, 29963, 30149, 30329, 30502, 30670, 30831, 30986, 31135, 31277, 31413, 31543, 31666, 31783, 31893, 31997, 32094, 32185, 32270, 32347, 32419, 32483, 32541, 32593, 32638, 32676, 32707, 32732, 32751, 32762, 32767, 32766, 32757, 32742, 32721, 32692, 32658, 32616, 32568, 32513, 32452, 32384, 32309, 32228, 32141, 32047, 31946, 31839, 31725, 31605, 31479, 31346, 31207, 31061, 30909, 30751, 30587, 30416, 30240, 30057, 29868, 29673, 29472, 29265, 29052, 28833, 28608, 28377, 28141, 27899, 27651, 27398, 27139, 26875, 26605, 26330, 26049, 25763, 25472, 25176, 24875, 24568, 24257, 23941, 23619, 23293, 22963, 22627, 22287, 21943, 21594, 21241, 20883, 20521, 20155, 19785, 19411, 19033, 18651, 18265, 17876, 17483, 17086, 16686, 16282, 15876, 15466, 15052, 14636, 14217, 13795, 13370, 12943, 12512, 12080, 11644, 11207, 10767, 10325, 9881, 9435, 8987, 8537, 8085, 7632, 7177, 6721, 6263, 5805, 5344, 4883, 4421, 3958, 3494, 3030, 2565, 2099, 1633, 1166, 700, 233, -233, -700, -1166, -1633, -2099, -2565, -3030, -3494, -3958, -4421, -4883, -5344, -5805, -6263, -6721, -7177, -7632, -8085, -8537, -8987, -9435, -9881, -10325, -10767, -11207, -11644, -12080, -12512, -12943, -13370, -13795, -14217, -14636, -15052, -15466, -15876, -16282, -16686, -17086, -17483, -17876, -18265, -18651, -19033, -19411, -19785, -20155, -20521, -20883, -21241, -21594, -21943, -22287, -22627, -22963, -23293, -23619, -23941, -24257, -24568, -24875, -25176, -25472, -25763, -26049, -26330, -26605, -26875, -27139, -27398, -27651, -27899, -28141, -28377, -28608, -28833, -29052, -29265, -29472, -29673, -29868, -30057, -30240, -30416, -30587, -30751, -30909, -31061, -31207, -31346, -31479, -31605, -31725, -31839, -31946, -32047, -32141, -32228, -32309, -32384, -32452, -32513, -32568, -32616, -32658, -32692, -32721, -32742, -32757, -32766, -32767, -32762, -32751, -32732, -32707, -32676, -32638, -32593, -32541, -32483, -32419, -32347, -32270, -32185, -32094, -31997, -31893, -31783, -31666, -31543, -31413, -31277, -31135, -30986, -30831, -30670, -30502, -30329, -30149, -29963, -29771, -29573, -29369, -29159, -28943, -28721, -28493, -28260, -28021, -27776, -27525, -27269, -27008, -26741, -26468, -26190, -25907, -25619, -25325, -25026, -24722, -24413, -24099, -23781, -23457, -23129, -22796, -22458, -22116, -21769, -21418, -21062, -20703, -20339, -19971, -19598, -19222, -18842, -18458, -18071, -17679, -17285, -16886, -16484, -16079, -15671, -15259, -14845, -14427, -14006, -13583, -13157, -12728, -12296, -11862, -11426, -10987, -10546, -10103, -9658, -9211, -8762, -8311, -7859, -7405, -6949, -6492, -6034, -5575, -5114, -4652, -4190, -3726, -3262, -2797, -2332, -1866, -1400, -933, -466, 0, 466, 933, 1400, 1866, 2332, 2797, 3262, 3726, 4190, 4652, 5114, 5575, 6034, 6492, 6949, 7405, 7859, 8311, 8762, 9211, 9658, 10103, 10546, 10987, 11426, 11862, 12296, 12728, 13157, 13583, 14006, 14427, 14845, 15259, 15671, 16079, 16484, 16886, 17285, 17679, 18071, 18458, 18842, 19222, 19598, 19971, 20339, 20703, 21062, 21418, 21769, 22116, 22458, 22796, 23129, 23457, 23781, 24099, 24413, 24722, 25026, 25325, 25619, 25907, 26190, 26468, 26741, 27008, 27269, 27525
  // Random
  // -23267, -28627, -22857, 28240, 13800, 30726, -24151, 26079, -13476, -12798, 13052, 13852, -22637, -6154, -3815, -12039, 25243, -1585, -19939, -8784, -28265, -26459, -11751, 11175, 29945, 6392, 2017, -26312, 705, 3937, 15719, 15254, 2106, -19522, -11782, 14779, 17287, -573, -4131, 1598, -17359, -2321, 29406, 10983, -1820, 10484, 2547, 21179, -8994, -2079, -27106, 10036, 24048, 20759, -22663, 30870, -23019, -6484, 10645, 28446, 5694, 29587, 2716, 28330, -31127, -24224, 11747, 4653, 25607, 2060, -13584, 18776, 3286, 4279, -23640, -19751, -29165, -26461, 1009, -26, 24934, 1737, 25904, 13741, 26638, -9855, 24739, 1151, 1288, 27717, -14507, 31321, 14853, 30335, 6779, -25100, -31174, 21443, -26019, 10443, -16230, -7792, -17010, 22850, 26999, -22520, -3965, -28776, 20422, 32717, -13509, 615, 3751, 14471, -31442, 331, -4401, -13910, -9235, -22272, -20351, -18042, -12559, -26528, -21608, -10967, -10773, 7318, 29416, 11987, -18385, 18446, -7565, -1826, 5991, -1501, -18115, 11245, -26602, 26281, -27812, 606, 10535, -24038, -9512, -28585, 17743, -23902, -5358, 14428, -6620, -11902, 29990, -1351, 229, 505, -20824, 2948, -10728, -8917, -30529, -8611, 10386, 8405, 29667, 1259, -933, 27763, 15110, -7538, 2579, -2260, 16781, 3587, 987, 10675, -12646, -26337, -15515, 10036, -10923, 19627, 23472, -19409, -25964, -15233, -12738, -17699, 21449, 12398, 31055, 3204, 10120, -5165, 28072, 3534, 8925, 8718, 12006, -14307, 3727, -2169, -9054, -32745, -27455, -2414, -30904, -27071, 29227, -1711, -32026, 16670, 4041, 11990, -6825, 19509, -10102, -5291, 14789, 13031, 27966, 3079, -30755, 18652, 8718, 17518, 27673, -21518, 26194, -7598, 8682, -30879, -26492, 25542, -683, 29625, -18786, -11302, 14478, -25560, 2884, 16250, -17512, -5658, 10514, -32180, 19268, 13426, -17484, 15865, 12636, 5169, -8869, 24014, 26874, 21372, -31006, 1717, 28024, 1712, 24846, 28640, 14211, 38, -32053, -23226, 4101, 10121, 17271, 67, 20471, -265, 17592, -17786, -14468, 836, 24620, -10300, -31533, 18124, -27177, 8895, -14010, 3583, 4616, -370, -1692, -24560, 7943, -15712, -548, 22854, 6585, -6472, -3219, -5611, -6953, 27266, 32132, -9528, 27921, -5179, 25555, -1361, 7012, 20560, -9756, 20686, -28590, -9269, 23420, -6441, -26236, -26378, -16303, -4482, -32143, 879, 28814, -15829, 13154, -32500, 10497, -15844, 27537, 12933, 24326, -8289, -25445, 5613, 3783, 19422, 13656, -28388, 10940, 23522, -8935, -10820, -23230, -6261, 8161, 16840, -23319, -14576, -20202, 9909, 14492, 17965, 830, 2347, -11266, -8371, -9564, -4490, 10044, -1236, -14600, 27197, 31869, 9030, 28833, 27173, -31152, 4385, 31150, 24565, -17190, 15066, 31896, -18756, 20622, -3244, -11415, 28206, 824, 11787, 17574, -32303, 23499, -23228, 24135, 29557, 11106, -12688, -1300, 16113, 4289, 8128, -10194, 8058, -24081, -13334, -22492, -20062, -21175, -31592, 11336, 26112, -14411, 29755, 8660, -19490, -11577, 17292, -8281, -2277, 3554, 4593, -2709, -5323, -8179, 10204, -17385, 18261, -301, 12645, -14775, -12287, -16381, 29835, -25494, 17111, 17776, 19593, 2789, 17686, -30471, -23637, -29774, -16137, 14721, -22862, 4031, -29039, -22289, 11175, 10518, -15373, 695, -23720, -24736, 14425, -9407, -25318, 2501, -5415, -21451, -20293, -19032, 27457, 28601, -11034, -9415, -8598, -30687, -26219, 31028, 9152, -20955, -30113, 31446, -23025, -14905, 384, -738, -871, 43, -5814, -6575, -12151, 13081, 14489, -3276, -24880, -27900, 5863, 7411, -21359, -26944, -9252, 15265, -12092, -8907, 17623, -13430, -3138, 23092, 10217, 13241, 1005, 11791, -12903, -12487, -13885, -8748, -7247, -12551, 1132, 16750, 29330, 9297, -22940, -2912, 7094, -3066, 20032, -13050, -26769, -32399, -23202, 13843, 18265
  // Mixed content
  0, 20065, 20774, 14478, 7238, -8053, -16118, -4051, 7534, 6075, 3660, -2261, -17285, -20472, -3071, 12656, 19351, 24507, 16764, -5807, -17284, -11343, -5570, 1128, 11683, 7992, -8598, -12980, -4950, 2096, 14516, 28344, 21538, 414, -11404, -16217, -18132, -4858, 13563, 13604, 3724, 32, -4475, -6513, 8151, 23989, 20258, 8508, -1704, -17249, -25082, -10049, 8615, 14091, 16355, 14067, -790, -9122, 1929, 12576, 13845, 15030, 7381, -13670, -23561, -13069, -737, 10830, 25231, 24491, 6096, -4544, -2850, -1845, 4676, 16574, 12215, -5964, -14129, -13027, -9898, 6065, 27202, 28380, 14823, 5084, -5222, -13918, -4550, 11428, 11365, 3816, -424, -9456, -14133, 1869, 21552, 25413, 22684, 15389, -4598, -19263, -11696, 681, 5865, 12445, 12521, -2447, -10764, -435, 10586, 17554, 26412, 21788, -1044, -16380, -15529, -11888, -1615, 16659, 20446, 7035, -458, -336, -1161, 7875, 23559, 21483, 4371, -7233, -15614, -21255, -8114, 14640, 21499, 16945, 13025, 2104, -8840, -766, 13847, 14491, 9531, 3725, -12102, -23332, -11514, 7094, 16637, 24423, 24493, 6412, -9454, -6591, -251, 3352, 11817, 11634, -5689, -16853, -11022, -2732, 8793, 26686, 29578, 11646, -3250, -9050, -14188, -8191, 9209, 13344, 2263, -4056, -7008, -10299, 1348, 22278, 26522, 16272, 6387, -8487, -23100, -16775, 1463, 8630, 9698, 10245, -523, -11784, -3252, 12037, 16701, 18293, 14505, -5708, -23916, -20524, -9316, -5, 14238, 20734, 7077, -5948, -4177, -816, 3751, 15842, 16850, -1764, -16792, -19304, -19174, -8705, 14023, 23853, 14256, 5119, -2037, -11764, -8128, 8128, 11764, 2037, -5119, -14256, -23853, -14023, 8705, 19174, 19304, 16792, 1764, -16850, -15842, -3751, 816, 4177, 5948, -7077, -20734, -14238, 5, 9316, 20524, 23916, 5708, -14505, -18293, -16701, -12037, 3252, 11784, 523, -10245, -9698, -8630, -1463, 16775, 23100, 8487, -6387, -16272, -26522, -22278, -1348, 10299, 7008, 4056, -2263, -13344, -9209, 8191, 14188, 9050, 3250, -11646, -29578, -26686, -8793, 2732, 11022, 16853, 5689, -11634, -11817, -3352, 251, 6591, 9454, -6412, -24493, -24423, -16637, -7094, 11514, 23332, 12102, -3725, -9531, -14491, -13847, 766, 8840, -2104, -13025, -16945, -21499, -14640, 8114, 21255, 15614, 7233, -4371, -21483, -23559, -7875, 1161, 336, 458, -7035, -20446, -16659, 1615, 11888, 15529, 16380, 1044, -21788, -26412, -17554, -10586, 435, 10764, 2447, -12521, -12445, -5865, -681, 11696, 19263, 4598, -15389, -22684, -25413, -21552, -1869, 14133, 9456, 424, -3816, -11365, -11428, 4550, 13918, 5222, -5084, -14823, -28380, -27202, -6065, 9898, 13027, 14129, 5964, -12215, -16574, -4676, 1845, 2850, 4544, -6096, -24491, -25231, -10830, 737, 13069, 23561, 13670, -7381, -15030, -13845, -12576, -1929, 9122, 790, -14067, -16355, -14091, -8615, 10049, 25082, 17249, 1704, -8508, -20258, -23989, -8151, 6513, 4475, -32, -3724, -13604, -13563, 4858, 18132, 16217, 11404, -414, -21538, -28344, -14516, -2096, 4950, 12980, 8598, -7992, -11683, -1128, 5570, 11343, 17284, 5807, -16764, -24507, -19351, -12656, 3071, 20472, 17285, 2261, -3660, -6075, -7534, 4051, 16118, 8053, -7238, -14478, -20774, -20065, 0, 20065, 20774, 14478, 7238, -8053, -16118, -4051, 7534, 6075, 3660, -2261, -17285, -20472, -3071, 12656, 19351, 24507, 16764, -5807, -17284, -11343, -5570, 1128, 11683, 7992, -8598, -12980, -4950, 2096, 14516, 28344, 21538, 414, -11404, -16217, -18132, -4858, 13563, 13604, 3724, 32, -4475, -6513, 8151, 23989, 20258, 8508, -1704, -17249, -25082, -10049, 8615, 14091, 16355, 14067, -790, -9122, 1929, 12576, 13845, 15030, 7381, -13670, -23561, -13069, -737, 10830, 25231, 24491, 6096
};

const q15_t* samples_512(void) {
  return _samples_512;
}

static const q15_t _samples_64[64] = {
  0, 16209, 4717, -14836, -9035, 12206, 12588, -8543, -15074, 4155, 16284, 583, -16114, -5273, 14579, 9516, -11809, -12953, 8039, 15293, -3588, -16338, -1166, 15998, 5822, -14304, -9985, 11398, 13302, -7526, -15493, 3017, 16371, 1747, -15862, -6364, 14010, 10441, -10971, -13634, 7003, 15673, -2441, -16383, -2326, 15706, 6897, -13699, -10884, 10531, 13949, -6471, -15833, 1863, 16375, 2902, -15530, -7422, 13370, 11313, -10077, -14246, 5931, 15973
};

const q15_t* samples_64(void) {
  return _samples_64;
}

